<!DOCTYPE html>
<html lang="en">

<head>

    <meta charset="UTF-8">
    <link rel="shortcut icon" type="image/x-icon" href="http://wechatpay.xiaoshuai2233@sina.com.me/okr/favicon.ico"/>
    <link rel="mask-icon" type="" href="../../static/favicon.ico" color="#111"/>
    <title> OKR </title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">


    <link rel='stylesheet prefetch' href='../../static/css/font-awesome.min.css' th:href="@{/css/font-awesome.min.css}">
    <link rel='stylesheet prefetch' href='../../static/css/google.fonts.css' th:href="@{/css/google.fonts.css}">
    <link th:href="@{/css/bootstrap.min.css}" rel="stylesheet"/>

    <style>
        .full-container {
            background-color: red;
            width: 100%;
            height: 100%;
            font-family: 'Roboto', sans-serif;
        }


        /* ########################   DEPARTMENT INFO  ############################*/

        .department-information {
            font-family: 'Roboto', sans-serif;
            display: none;
            box-shadow: 0 0 5px #999999;
            position: absolute;
            max-width: 200px;
            top: 60px;
            left: 20px;
            padding: 10px;
            background-color: white;
        }

        .department-information .dept-name {
            color: #26a69a;
            font-weight: bold;
        }

        .department-information .dept-description {
            margin-top: 10px;
            color: #959b9a;
            font-size: 13px;
        }

        .department-information .dept-emp-count {
            margin-top: 10px;
            color: #959b9a;
            font-size: 13px;
        }

        /* ############################## SEARCHBOX ######################################### */

        .user-search-box {
            overflow: hidden;
            position: absolute;
            right: 0;
            height: 100%;
            top: 0;
            width: 0;
            background-color: white;
            border: 1px solid #c7dddb;
            font-family: 'Roboto', sans-serif;
            font-size: 14px;
            line-height: 1.5;
        }

        ::-webkit-input-placeholder {
            /* WebKit, Blink, Edge */
            color: #bcbcc4;
            opacity: 0.5;
        }

        :-moz-placeholder {
            /* Mozilla Firefox 4 to 18 */
            color: #bcbcc4;
            opacity: 0.5;
        }

        ::-moz-placeholder {
            /* Mozilla Firefox 19+ */
            color: #bcbcc4;
            opacity: 0.5;
        }

        :-ms-input-placeholder {
            /* Internet Explorer 10-11 */
            color: #bcbcc4;
            opacity: 0.5;
        }

        .user-search-box .input-box {
            width: 100%;
            height: 200px;
            top: 0;
            background-color: #e8efee;
        }

        .user-search-box .close-button-wrapper i {
            margin: 10px;
            margin-left: 9%;
            font-size: 60px;
            font-weight: 400;
            color: #aa1414;
        }

        .user-search-box input {
            color: gray !important;
            background-color: transparent;
            border: none;
            border-bottom: 1px solid #9e9e9e;
            border-radius: 0;
            outline: none;
            height: 3rem;
            width: 100%;
            font-size: 1rem;
            margin: 0 0 20px 0;
            padding: 0;
            box-shadow: none;
            box-sizing: content-box;
            transition: all 0.3s;
        }

        .user-search-box input:focus {
            border-bottom: 1px solid #26a69a;
            box-shadow: 0 1px 0 0 #26a69a;
        }

        .user-search-box .result-header {
            background-color: white;
            font-weight: 700;
            padding: 12px;
            color: gray;
            border-top: 2px solid #d3e8e5;
            border-bottom: 1px solid #d3e8e5;
        }

        .user-search-box .result-list {
            position: absolute;
            max-height: 100%;
            min-width: 100%;
            overflow: auto;
        }

        .user-search-box .buffer {
            width: 100%;
            height: 400px;
        }

        .user-search-box .list-item {
            clear: both;
            background-color: white;
            position: relative;
            background-color: white;
            width: 100%;
            height: 100px;
            border-top: 1px solid #d3e8e5;
        }

        .user-search-box .list-item a {
            display: inline;
            margin: 0;
        }

        .user-search-box .list-item .image-wrapper {
            float: left;
            width: 100px;
            height: 100px;
        }

        .user-search-box .list-item .image {
            width: 70px;
            height: 70px;
            margin-left: 15px;
            margin-top: 15px;
            border-radius: 5px;
        }

        .user-search-box .list-item .description {
            padding: 15px;
            padding-left: 0px;
            float: left;
            width: 180px;
        }

        .user-search-box .list-item .buttons {
            padding: 15px;
            padding-left: 0px;
            float: left;
            width: auto;
        }

        .user-search-box .list-item .description .name {
            font-size: 15px;
            color: #aa1414;
            font-weight: 900;
            margin: 0;
            padding: 0;
            letter-spacing: 1px;
        }

        .user-search-box .list-item .description .position-name {
            color: #59525b;
            letter-spacing: 1px;
            font-size: 12px;
            font-weight: 900;
            margin: 0;
            margin-top: 3px;
            padding: 0;
        }

        .user-search-box .list-item .description .area {
            color: #91a4a5;
            letter-spacing: 1px;
            font-size: 12px;
            font-weight: 400;
            margin: 0;
            margin-top: 3px;
            padding: 0;
        }

        .user-search-box .list-item .btn-locate {
            margin-top: 30px;
        }

        .user-search-box .list-item .btn-search-box {
            font-size: 10px;
        }

        .user-search-box .close-button-wrapper i:hover {
            color: black;
            cursor: pointer;
        }

        .user-search-box .input-wrapper {
            width: 80%;
            margin: 0 auto;
        }

        .user-search-box .input-bottom-placeholder {
            margin-top: -16px;
            color: #bcbcc4;
            letter-spacing: 1px;
        }


        /* ############################### Tooltip css ########################### */

        .profile-image-wrapper {
            background-size: 210px;
            margin: 30px;
            border-radius: 50%;
            width: 210px;
            height: 210px;
        }

        .customTooltip-wrapper {
            font-family: 'Roboto', sans-serif;
            opacity: 0;
            /* NEW */
            display: none;
            position: absolute;
            height: 100%;
            width: 30%;
            top: 0px;
            right: 0px;
        }

        .customTooltip {
            background: white;
            width: 100%;
            height: 100%;
            box-shadow: 0 0 5px #999999;
            color: #333;
            position: absolute;
            font-size: 12px;
            right: 0px;
            text-align: center;
            top: 0px;
            z-index: 10;
            text-align: left;
        }

        .tooltip-hr {
            width: 70px;
            background-color: #91a4a5;
            height: 1px;
            margin-left: auto;
            margin-right: auto;
            margin-top: -17px;
            margin-bottom: 25px;
        }

        .tooltip-desc {
            padding-left: 10px;
            margin-top: -20px;
            margin-left: 20px;
            overflow: auto;
        }

        .tooltip-desc .name {
            color: #962828;
            font-weight: 900;
            letter-spacing: 1px;
            font-size: 24px;
            font-weight: bold;
            margin-bottom: 2px;
            text-decoration: none;
        }

        .tooltip-desc .name:hover {
            text-decoration: underline;
        }

        .tooltip-desc .position {
            color: #59525b;
            letter-spacing: 1px;
            font-size: 17px;
            font-weight: 500;
            margin-bottom: 2px;
            margin-top: 0px;
        }

        .tooltip-desc .area {
            color: #91a4a5;
            letter-spacing: 1px;
            font-size: 16px;
            font-weight: 400;
            margin-bottom: 2px;
            margin-top: 7px;
        }

        .tooltip-desc .office {
            color: #91a4a5;
            line-height: 160%;
            font-size: 14px;
            font-weight: 400;
            margin-bottom: -10px;
            margin-top: -5px;
        }

        .tooltip-desc .tags-wrapper .title {
            display: inline-block;
            float: left;
        }

        .tooltip-desc .tags-wrapper .tags {
            display: inline-block;
            float: left;
        }

        .bottom-tooltip-hr {
            width: 100%;
            background-color: #58993e;
            height: 3px;
            margin-left: auto;
            margin-right: auto;
            margin-top: -17px;
        }

        .btn-tooltip-department {
            margin-top: 20px;
        }

        .btn.disabled {
            background-color: #DFDFDF !important;
            box-shadow: none;
            color: #9F9F9F !important;
            cursor: default;
        }

        .btn {
            border: none;
            border-radius: 2px;
            height: 36px;
            line-height: 36px;
            outline: 0;
            text-transform: uppercase;
            vertical-align: middle;
            -webkit-tap-highlight-color: transparent;
            text-decoration: none;
            color: #fff;
            background-color: #26a69a;
            text-align: center;
            letter-spacing: .5px;
            transition: .2s ease-out;
            cursor: pointer;
            box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12);
        }

        .btn:hover {
            box-shadow: 0 5px 11px 0 rgba(0, 0, 0, 0.18), 0 4px 15px 0 rgba(0, 0, 0, 0.15);
        }

        .btn.disabled:hover {
            box-shadow: none;
        }


        /* ####################################### TAGS ###################################### */

        .tags {
            list-style: none;
            margin-top: -9px;
            margin-left: 5px;
            overflow: hidden;
            padding: 0;
        }

        .tags-wrapper {
            font-size: 2.28rem;
            line-height: 110%;
            margin: 1.14rem 0 0.912rem 0;
        }

        .tags-wrapper .title {
            color: #91a4a5;
            font-size: 24px;
        }

        .tags li {
            float: left;
        }

        .tag {
            font-size: 11px;
            background: #E1ECF4;
            border-radius: 2px;
            color: # #39739d;
            display: inline-block;
            height: 20px;
            line-height: 20px;
            padding: 0 5px 0 5px;
            position: relative;
            margin: 0 5px 5px 0;
            text-decoration: none;
            -webkit-transition: color 0.2s;
        }


        /* #############################   Buttons  ############################################*/

        .btn-search {
            top: 80px;
        }

        .btn-fullscreen {
            top: 20px;
        }

        .btn-back {
            top: 20px;
            left: 20px;
            display: none;
        }

        .btn-show-my-self {
            top: 50px;
        }

        .btn-action {
            position: absolute;
            right: 25px;
            height: 26px;
            color: white;
            background-color: #aa1414;
            border: 1px solid black;
            border-radius: 12px;
            cursor: pointer;
            font-size: 15px;
            font-family: 'Roboto', sans-serif;
        }

        .btn-action:focus {
            outline: 0;
            background-color: #aa1414;
        }

        .btn-action:hover {
            background-color: #490b0b;
        }

        .btn-action i {
            font-size: 14px;
        }

        .btn-action .icon {
            background-color: #c19e45;
            padding: 5px 6px 5px 6px;
            border-radius: 11px;
            margin-right: -7px;
        }


        /* ############################################## SVG ################################# */

        .nodeHasChildren {
            fill: white;
        }

        .nodeDoesNotHaveChildren {
            fill: white;
        }

        .nodeRepresentsCurrentUser {
            stroke: Chartreuse;
            stroke-width: 3;
        }

        text {
            fill: dimgray;
        }

        .link {
            fill: none;
            stroke: #ccc;
            stroke-width: 1.5px;
        }

        .node {
            cursor: pointer;
        }

        .node-collapse {
            stroke: grey;
        }

        .node-collapse-right-rect {
            fill: #70c645;
            stroke: #70c645;
        }

        .node text {
            fill: white;
            font-family: "Segoe UI", Arial, sans-serif;
            font-size: 10px;
        }

        .node circle {
            stroke-width: 1px;
            stroke: #70c645;
            fill: #70c645;
        }

        .node-group .emp-name {
            fill: #962828;
            font-size: 12px;
            font-weight: 600
        }

        .node-group .emp-position-name {
            fill: #59525b;
            font-size: 11px;
        }

        .node-group .emp-area {
            fill: #91a4a5;
            width: 100px;
            height: 30px;
            text-overflow: ellipsis;
            white-space: nowrap;
            font-size: 10px;
        }

        .node-group .emp-left-text {
            fill: #91a4a5;
            width: 200px;
            height: 76px;
            text-overflow: ellipsis;
            white-space: nowrap;
            font-size: 10px;
        }

        .node-group .emp-count,
        .node-group .emp-cou

        ;
        nt-icon {
            fill: #91a4a5;
            font-size: 12px;
        }
    </style>


</head>

<body translate="no">

<div id="full-container">
    <button class="btn-action btn-fullscreen" onclick="params.funcs.toggleFullScreen()">Fullscreen <span class='icon'/>
        <i class="fa fa-arrows-alt" aria-hidden="true"></i></span></button>
    <!--    <button class="btn-action btn-show-my-self" onclick="params.funcs.showMySelf()"> Show myself <span class='icon'/> <i-->
    <!--            class="fa fa-user" aria-hidden="true"></i></span></button>-->

    <!--    <button class=" btn-action btn-search" onclick="params.funcs.search()"> Search <span class='icon'/> <i-->
    <!--            class="fa fa-search" aria-hidden="true"></i></span></button>-->

    <button class=" btn-action btn-back" onclick="params.funcs.back()"> Back <span class='icon'/> <i
            class="fa fa-arrow-left" aria-hidden="true"></i></span></button>

    <div class="department-information">
        <div class="dept-name">
            dept name
        </div>
        <div class="dept-emp-count">
            dept description test, this is department description
        </div>
        <div class="dept-description">
            dept description test, this is department description
        </div>
    </div>

    <div class="user-search-box">
        <div class="input-box">
            <div class="close-button-wrapper"><i onclick="params.funcs.closeSearchBox()" class="fa fa-times"
                                                 aria-hidden="true"></i></div>
            <div class="input-wrapper">
                <input type="text" class="search-input" placeholder="Search"/>
                <div class="input-bottom-placeholder">By Firstname, Lastname, Tags</div>
            </div>
            <div>
            </div>
        </div>
        <div class="result-box">
            <div class="result-header"> RESULTS</div>
            <div class="result-list">


                <div class="buffer"></div>
            </div>
        </div>
    </div>
    <div id="svgChart"></div>
    <!--
     <button class="btn btn-expand" onclick="params.funcs.expandAll()">Expand All</button>
  -->
</div>

<script src='../../static/js/d3.min.js' th:src="@{/js/d3.min.js}"></script>
<script th:src="@{/js/jquery.min.js}"></script>

<script th:inline="javascript">

    var data = [(${data})];
    var params = {
        selector: "#svgChart",
        dataLoadUrl: "http://wechatpay.xiaoshuai2233@sina.com.me/okr/data.json",
        chartWidth: window.innerWidth - 40,
        chartHeight: window.innerHeight - 40,
        funcs: {
            showMySelf: null,
            search: null,
            closeSearchBox: null,
            clearResult: null,
            findInTree: null,
            reflectResults: null,
            departmentClick: null,
            back: null,
            toggleFullScreen: null,
            locate: null
        },
        data: null
    }
    params.data = data;
    params.pristinaData = JSON.parse(JSON.stringify(data));
    drawOrganizationChart(params);
    // d3.json(params.dataLoadUrl, function (data) {
    //     params.data = data;
    //     params.pristinaData = JSON.parse(JSON.stringify(data));
    //     drawOrganizationChart(params);
    // })

    function drawOrganizationChart(params) {
        listen();

        params.funcs.showMySelf = showMySelf;
        params.funcs.expandAll = expandAll;
        params.funcs.search = searchUsers;
        params.funcs.closeSearchBox = closeSearchBox;
        params.funcs.findInTree = findInTree;
        params.funcs.clearResult = clearResult;
        params.funcs.reflectResults = reflectResults;
        params.funcs.departmentClick = departmentClick;
        params.funcs.back = back;
        params.funcs.toggleFullScreen = toggleFullScreen;
        params.funcs.locate = locate;

        var attrs = {
            EXPAND_SYMBOL: '\uf067',
            COLLAPSE_SYMBOL: '\uf068',
            selector: params.selector,
            root: params.data,
            width: params.chartWidth,
            height: params.chartHeight,
            wordWrap: 'break-word',
            index: 0,
            nodePadding: 9,
            collapseCircleRadius: 7,
            nodeHeight: 100,
            nodeWidth: 210,
            duration: 750,
            rootNodeTopMargin: 20,
            minMaxZoomProportions: [0.05, 3],
            linkLineSize: 180,
            collapsibleFontSize: '10px',
            userIcon: '\uf007',
            nodeStroke: "#ccc",
            nodeStrokeWidth: '1px'
        }

        var dynamic = {}
        dynamic.nodeImageWidth = attrs.nodeHeight * 100 / 140;
        dynamic.nodeImageHeight = attrs.nodeHeight - 2 * attrs.nodePadding;
        dynamic.nodeTextLeftMargin = attrs.nodePadding * 2 + dynamic.nodeImageWidth
        dynamic.rootNodeLeftMargin = attrs.width / 2;
        dynamic.nodePositionNameTopMargin = attrs.nodePadding + 8 + dynamic.nodeImageHeight / 4 * 1
        dynamic.nodeChildCountTopMargin = attrs.nodePadding + 14 + dynamic.nodeImageHeight / 4 * 3

        var tree = d3.layout.tree().nodeSize([attrs.nodeWidth + 40, attrs.nodeHeight]);
        var diagonal = d3.svg.diagonal()
            .projection(function (d) {
                return [d.x + attrs.nodeWidth / 2, d.y + attrs.nodeHeight / 2];
            });

        var zoomBehaviours = d3.behavior
            .zoom()
            .scaleExtent(attrs.minMaxZoomProportions)
            .on("zoom", redraw);

        var svg = d3.select(attrs.selector)
            .append("svg")
            .attr("width", attrs.width)
            .attr("height", attrs.height)
            .call(zoomBehaviours)
            .append("g")
            .attr("transform", "translate(" + attrs.width / 2 + "," + 20 + ")");

        //necessary so that zoom knows where to zoom and unzoom from
        zoomBehaviours.translate([dynamic.rootNodeLeftMargin, attrs.rootNodeTopMargin]);

        attrs.root.x0 = 0;
        attrs.root.y0 = dynamic.rootNodeLeftMargin;

        if (params.mode != 'department') {
            // adding unique values to each node recursively
            var uniq = 1;
            addPropertyRecursive('uniqueIdentifier', function (v) {

                return uniq++;
            }, attrs.root);

        }

        expand(attrs.root);
        if (attrs.root.children) {
            attrs.root.children.forEach(collapse);
        }

        update(attrs.root);

        d3.select(attrs.selector).style("height", attrs.height);

        var tooltip = d3.select('body')
            .append('div')
            .attr('class', 'customTooltip-wrapper');

        function update(source, param) {
            // Compute the new tree layout.
            var nodes = tree.nodes(attrs.root)
                    .reverse(),
                links = tree.links(nodes);

            // Normalize for fixed-depth.
            nodes.forEach(function (d) {
                d.y = d.depth * attrs.linkLineSize;
            });

            // Update the nodes��
            var node = svg.selectAll("g.node")
                .data(nodes, function (d) {
                    return d.singleId || (d.singleId = ++attrs.index);
                });

            // Enter any new nodes at the parent's previous position.
            var nodeEnter = node.enter()
                .append("g")
                .attr("class", "node")
                .attr("transform", function (d) {
                    return "translate(" + source.x0 + "," + source.y0 + ")";
                })

            var nodeGroup = nodeEnter.append("g")
                .attr("class", "node-group")


            nodeGroup.append("rect")
                .attr("width", attrs.nodeWidth)
                .attr("height", attrs.nodeHeight)
                .attr("data-node-group-id", function (d) {
                    return d.uniqueIdentifier;
                })
                .attr("class", function (d) {
                    var res = "";
                    if (d.isLoggedUser) res += 'nodeRepresentsCurrentUser ';
                    res += d._children || d.children ? "nodeHasChildren" : "nodeDoesNotHaveChildren";
                    return res;
                });

            var collapsiblesWrapper =
                nodeEnter.append('g')
                    .attr('data-id', function (v) {
                        return v.uniqueIdentifier;
                    });

            var collapsibleRects = collapsiblesWrapper.append("rect")
                .attr('class', 'node-collapse-right-rect')
                .attr('height', attrs.collapseCircleRadius)
                .attr('fill', 'black')
                .attr('x', attrs.nodeWidth - attrs.collapseCircleRadius)
                .attr('y', attrs.nodeHeight - 7)
                .attr("width", function (d) {
                    if (d.children || d._children) return attrs.collapseCircleRadius;
                    return 0;
                })

            var collapsibles =
                collapsiblesWrapper.append("circle")
                    .attr('class', 'node-collapse')
                    .attr('cx', attrs.nodeWidth - attrs.collapseCircleRadius)
                    .attr('cy', attrs.nodeHeight - 7)
                    .attr("", setCollapsibleSymbolProperty);

            //hide collapse rect when node does not have children
            collapsibles.attr("r", function (d) {
                if (d.children || d._children) return attrs.collapseCircleRadius;
                return 0;
            })
                .attr("height", attrs.collapseCircleRadius)

            collapsiblesWrapper.append("text")
                .attr('class', 'text-collapse')
                .attr("x", attrs.nodeWidth - attrs.collapseCircleRadius)
                .attr('y', attrs.nodeHeight - 3)
                .attr('width', attrs.collapseCircleRadius)
                .attr('height', attrs.collapseCircleRadius)
                .attr('word-wrap', "break-word")
                .style('font-size', attrs.collapsibleFontSize)
                .attr("text-anchor", "middle")
                .style('font-family', 'FontAwesome')
                .text(function (d) {
                    return d.collapseText;
                })

            collapsiblesWrapper.on("click", click);

            nodeGroup.append("text")
                .attr("x", dynamic.nodeTextLeftMargin)
                .attr("y", attrs.nodePadding + 10)
                .attr('class', 'emp-name')
                .attr('word-wrap', "break-word")
                .attr("text-anchor", "left")
                .text(function (d) {
                    return d.name.trim();
                })
                .call(wrap, attrs.nodeWidth);

            nodeGroup.append("text")
                .attr("x", dynamic.nodeTextLeftMargin)
                .attr("y", dynamic.nodePositionNameTopMargin)
                .attr('class', 'emp-position-name')
                .attr('word-wrap', "break-word")
                .attr("dy", ".35em")
                .attr("text-anchor", "left")
                .text(function (d) {
                    var position = d.positionName.substring(0, 27);
                    if (position.length < d.positionName.length) {
                        position = position.substring(0, 24) + '...'
                    }
                    return position;
                })

            nodeGroup.append("foreignObject")
                .attr("x", function(d){
                    if(d.tags=="p")
                    {
                        return  dynamic.nodeTextLeftMargin;
                    }
                    else {
                        return  5;
                    }
                })
                .attr("y",function(d){
                    if(d.tags=="p")
                    {
                        return   attrs.nodePadding + 10 + dynamic.nodeImageHeight / 4 * 2;
                    }
                    else {
                        return  30;
                    }
                })
                .attr('class', function(d){
                    if(d.tags=="p")
                    {
                        return  'emp-area';
                    }
                    else {
                        return  'emp-left-text';
                    }
                })
                .attr("dy", ".35em")
                .attr("text-anchor", "left")
                .html(function (d) {
                    var textBody = "<body xmlns=\"http://www.w3.org/1999/xhtml\">\n" +
                            "        <div style='height:70px;font-size:10px;margin:0;word-wrap: break-word;word-break:break-all; white-space:pre-wrap;overflow:hidden;text-overflow:ellipsis;'><p >"+d.area+"</p></div>\n" +
                            "      </body>";
                    return textBody;
                })

            nodeGroup.append("text")
                .attr("x", dynamic.nodeTextLeftMargin)
                .attr("y", dynamic.nodeChildCountTopMargin)
                .attr('class', 'emp-count-icon')
                .attr("text-anchor", "left")
                .style('font-family', 'FontAwesome')
                .text(function (d) {
                    if (d.children || d._children) return attrs.userIcon;
                });

            nodeGroup.append("text")
                .attr("x", dynamic.nodeTextLeftMargin + 13)
                .attr("y", dynamic.nodeChildCountTopMargin)
                .attr('class', 'emp-count')
                .attr("text-anchor", "left")

                .text(function (d) {
                    if (d.children) return d.children.length;
                    if (d._children) return d._children.length;
                    return;
                })

            nodeGroup.append("defs").append("svg:clipPath")
                .attr("id", "clip")
                .append("svg:rect")
                .attr("id", "clip-rect")
                .attr("rx", 3)
                .attr('x', attrs.nodePadding)
                .attr('y', 2 + attrs.nodePadding)
                .attr('width', dynamic.nodeImageWidth)
                .attr('fill', 'none')
                .attr('height', dynamic.nodeImageHeight - 4)

            nodeGroup.append("svg:image")
                .attr('y', 2 + attrs.nodePadding)
                .attr('x', attrs.nodePadding)
                .attr('preserveAspectRatio', 'none')
                .attr('width', dynamic.nodeImageWidth)
                .attr('height', dynamic.nodeImageHeight - 4)
                .attr('clip-path', "url(#clip)")
                .attr("xlink:href", function (v) {
                    if(v.tags=="p")
                    {

                    }
                    return v.imageUrl;
                })

            // Transition nodes to their new position.
            var nodeUpdate = node.transition()
                .duration(attrs.duration)
                .attr("transform", function (d) {
                    return "translate(" + d.x + "," + d.y + ")";
                })

            //todo replace with attrs object
            nodeUpdate.select("rect")
                .attr("width", attrs.nodeWidth)
                .attr("height", attrs.nodeHeight)
                .attr('rx', 3)
                .attr("stroke", function (d) {
                    if (param && d.uniqueIdentifier == param.locate) {
                        return '#a1ceed'
                    }
                    return attrs.nodeStroke;
                })
                .attr('stroke-width', function (d) {
                    if (param && d.uniqueIdentifier == param.locate) {
                        return 6;
                    }
                    return attrs.nodeStrokeWidth
                })

            // Transition exiting nodes to the parent's new position.
            var nodeExit = node.exit().transition()
                .duration(attrs.duration)
                .attr("transform", function (d) {
                    return "translate(" + source.x + "," + source.y + ")";
                })
                .remove();

            nodeExit.select("rect")
                .attr("width", attrs.nodeWidth)
                .attr("height", attrs.nodeHeight)

            // Update the links
            var link = svg.selectAll("path.link")
                .data(links, function (d) {
                    return d.target.id;
                });

            // Enter any new links at the parent's previous position.
            link.enter().insert("path", "g")
                .attr("class", "link")
                .attr("x", attrs.nodeWidth / 2)
                .attr("y", attrs.nodeHeight / 2)
                .attr("d", function (d) {
                    var o = {
                        x: source.x0,
                        y: source.y0
                    };
                    return diagonal({
                        source: o,
                        target: o
                    });
                });

            // Transition links to their new position.
            link.transition()
                .duration(attrs.duration)
                .attr("d", diagonal)
            ;

            // Transition exiting nodes to the parent's new position.
            link.exit().transition()
                .duration(attrs.duration)
                .attr("d", function (d) {
                    var o = {
                        x: source.x,
                        y: source.y
                    };
                    return diagonal({
                        source: o,
                        target: o
                    });
                })
                .remove();

            // Stash the old positions for transition.
            nodes.forEach(function (d) {
                d.x0 = d.x;
                d.y0 = d.y;
            });

            if (param && param.locate) {
                var x;
                var y;

                nodes.forEach(function (d) {
                    if (d.uniqueIdentifier == param.locate) {
                        x = d.x;
                        y = d.y;
                    }
                });


                // normalize for width/height
                var new_x = (-x + (window.innerWidth / 2));
                var new_y = (-y + (window.innerHeight / 2));

                // move the main container g
                svg.attr("transform", "translate(" + new_x + "," + new_y + ")")
                zoomBehaviours.translate([new_x, new_y]);
                zoomBehaviours.scale(1);
            }

            if (param && param.centerMySelf) {
                var x;
                var y;

                nodes.forEach(function (d) {
                    if (d.isLoggedUser) {
                        x = d.x;
                        y = d.y;
                    }

                });

                // normalize for width/height
                var new_x = (-x + (window.innerWidth / 2));
                var new_y = (-y + (window.innerHeight / 2));

                // move the main container g
                svg.attr("transform", "translate(" + new_x + "," + new_y + ")")
                zoomBehaviours.translate([new_x, new_y]);
                zoomBehaviours.scale(1);
            }

            /*################  TOOLTIP  #############################*/

            function getTagsFromCommaSeparatedStrings(tags) {
                return tags.split(',').map(function (v) {
                    return '<li><div class="tag">' + v + '</div></li>  '
                }).join('');
            }

            function tooltipContent(item) {
                // console.log(item);
                var strVar = "";
                $.ajax({
                    type: "post",
                    url: "/okr/treeMap/list",
                    async: false,
                    data: {
                        "id": item.id,"parentId":item.parent.id
                    },
                    success: function (r) {
                        strVar += "  <div class=\"customTooltip\"> <div class=\"ibox\">";
                        strVar += " <div class=\"panel panel-success\">\n" +
                            "                                    <div class=\"panel-heading\">\n" +
                            "                                       " + item.name + "" +
                            "                                    </div>\n" +
                            "                                    <div class=\"panel-body\">\n" +
                            "                                        <p>" + item.area + "</p>\n" +
                            "                                    </div>\n" +
                            "                                </div>";
                        if (r.length > 0) {
                            for (var i = 0; i < r.length; i++) {
                                strVar += "" +
                                    "                                <div class=\"panel panel-primary\">\n" +
                                    "                                    <div class=\"panel-heading\">\n" +
                                    "                         " + r[i].priority + "&nbsp&nbsp&nbsp&nbsp&nbsp "+r[i].deptName+"" +
                                    "                                    </div>\n" +
                                    "                                    <div class=\"panel-body\">\n" +
                                    "                                        <p>" + r[i].content + "</p>\n" +
                                    "                                    </div>\n" +
                                    "                                    <div class=\"panel-footer\">\n" +
                                    "                        <div class=\"row  m-t-sm\">\n" +
                                    "                            <div class=\"col-sm-4\">\n" +
                                    "                                <div class=\"font-bold\">信心指数</div>\n" +
                                    "                                "+ r[i].confidenceStar +" "+
                                    "                            </div>\n" +
                                    "                            <div class=\"col-sm-4\">\n" +
                                    "                                <div class=\"font-bold\">目标评分</div>\n" +
                                    "                                "+ r[i].scoreStar +" "+
                                    "                            </div>\n" +
                                    "                            <div class=\"col-sm-4 text-right\">\n" +
                                    "                                <div class=\"font-bold\">目标进度</div>\n" +
                                    "                                "+ r[i].process +" "+
                                    "                            </div>\n" +
                                    "                        </div>" +
                                    "                                    </div>\n" +
                                    "                                </div>\n" +
                                    "                           ";
                                // strVar += "    <div class=\"bottom-tooltip-hr\"><\/div>";
                            }
                        }

                        strVar += " <\/div> <\/div>";
                        strVar += "";
                    }
                });
                return strVar;
            }

            function tooltipHoverHandler(d) {
                var content = tooltipContent(d);
                tooltip.html(content);

                tooltip.transition()
                    .duration(200).style("opacity", "1").style('display', 'block');
                d3.select(this).attr('cursor', 'pointer').attr("stroke-width", 50);

                var y = d3.event.pageY;
                var x = d3.event.pageX;

                //restrict tooltip to fit in borders
                if (y < 220) {
                    y += 220 - y;
                    x += 130;
                }

                if (y > attrs.height - 300) {
                    y -= 300 - (attrs.height - y);
                }

                // tooltip.style('top', (y - 300) + 'px')
                //     .style('left', (x - 470) + 'px');
            }

            function tooltipOutHandler() {
                tooltip.transition()
                    .duration(200)
                    .style('opacity', '0').style('display', 'none');
                d3.select(this).attr("stroke-width", 5);

            }

            nodeGroup.on('click', tooltipHoverHandler);

            nodeGroup.on('dblclick', tooltipOutHandler);

            function equalToEventTarget() {
                return this == d3.event.target;
            }

            d3.select("body").on("click", function () {
                var outside = tooltip.filter(equalToEventTarget).empty();
                if (outside) {
                    tooltip.style('opacity', '0').style('display', 'none');
                }
            });

        }

        // Toggle children on click.
        function click(d) {

            d3.select(this).select("text").text(function (dv) {

                if (dv.collapseText == attrs.EXPAND_SYMBOL) {
                    dv.collapseText = attrs.COLLAPSE_SYMBOL
                } else {
                    if (dv.children) {
                        dv.collapseText = attrs.EXPAND_SYMBOL
                    }
                }
                return dv.collapseText;

            })

            if (d.children) {
                d._children = d.children;
                d.children = null;
            } else {
                d.children = d._children;
                d._children = null;
            }
            update(d);

        }

        //########################################################

        //Redraw for zoom
        function redraw() {
            svg.attr("transform",
                "translate(" + d3.event.translate + ")" +
                " scale(" + d3.event.scale + ")");
        }

        // #############################   Function Area #######################
        function wrap(text, width) {

            text.each(function () {
                var text = d3.select(this),
                    words = text.text().split(/\s+/).reverse(),
                    word,
                    line = [],
                    lineNumber = 0,
                    lineHeight = 1.1, // ems
                    x = text.attr("x"),
                    y = text.attr("y"),
                    dy = 0, //parseFloat(text.attr("dy")),
                    tspan = text.text(null)
                        .append("tspan")
                        .attr("x", x)
                        .attr("y", y)
                        .attr("dy", dy + "em");
                while (word = words.pop()) {
                    line.push(word);
                    tspan.text(line.join(" "));
                    if (tspan.node().getComputedTextLength() > width) {
                        line.pop();
                        tspan.text(line.join(" "));
                        line = [word];
                        tspan = text.append("tspan")
                            .attr("x", x)
                            .attr("y", y)
                            .attr("dy", ++lineNumber * lineHeight + dy + "em")
                            .text(word);
                    }
                }
            });
        }

        function addPropertyRecursive(propertyName, propertyValueFunction, element) {
            if (element[propertyName]) {
                element[propertyName] = element[propertyName] + ' ' + propertyValueFunction(element);
            } else {
                element[propertyName] = propertyValueFunction(element);
            }
            if (element.children) {
                element.children.forEach(function (v) {
                    addPropertyRecursive(propertyName, propertyValueFunction, v)
                })
            }
            if (element._children) {
                element._children.forEach(function (v) {
                    addPropertyRecursive(propertyName, propertyValueFunction, v)
                })
            }
        }

        function departmentClick(item) {
            hide(['.customTooltip-wrapper']);

            if (item.type == 'department' && params.mode != 'department') {
                //find third level department head user
                var found = false;
                var secondLevelChildren = params.pristinaData.children;
                parentLoop:
                    for (var i = 0; i < secondLevelChildren.length; i++) {
                        var secondLevelChild = secondLevelChildren[i];
                        var thirdLevelChildren = secondLevelChild.children ? secondLevelChild.children : secondLevelChild._children;

                        for (var j = 0; j < thirdLevelChildren.length; j++) {
                            var thirdLevelChild = thirdLevelChildren[j];
                            if (thirdLevelChild.unit.value.trim() == item.value.trim()) {
                                clear(params.selector);

                                hide(['.btn-action']);
                                show(['.btn-action.btn-back', '.btn-action.btn-fullscreen', '.department-information']);
                                set('.dept-name', item.value);

                                set('.dept-emp-count', "Employees Quantity - " + getEmployeesCount(thirdLevelChild));
                                set('.dept-description', thirdLevelChild.unit.desc);

                                params.oldData = params.data;

                                params.data = deepClone(thirdLevelChild);
                                found = true;
                                break parentLoop;
                            }
                        }
                    }
                if (found) {
                    params.mode = "department";
                    params.funcs.closeSearchBox();
                    drawOrganizationChart(params);

                }

            }
        }

        function getEmployeesCount(node) {
            var count = 1;
            countChilds(node);
            return count;

            function countChilds(node) {
                var childs = node.children ? node.children : node._children;
                if (childs) {
                    childs.forEach(function (v) {
                        count++;
                        countChilds(v);
                    })
                }
            }
        }

        function reflectResults(results) {
            var htmlStringArray = results.map(function (result) {
                var strVar = "";
                strVar += "         <div class=\"list-item\">";
                strVar += "          <a >";
                strVar += "            <div class=\"image-wrapper\">";
                strVar += "              <img class=\"image\" src=\"" + result.imageUrl + "\"\/>";
                strVar += "            <\/div>";
                strVar += "            <div class=\"description\">";
                strVar += "              <p class=\"name\">" + result.name + "<\/p>";
                strVar += "               <p class=\"position-name\">" + result.positionName + "<\/p>";
                strVar += "               <p class=\"area\">" + result.area + "<\/p>";
                strVar += "            <\/div>";
                strVar += "            <div class=\"buttons\">";
                strVar += "              <a target='_blank' href='" + result.profileUrl + "'><button class='btn-search-box btn-action'>View Profile<\/button><\/a>";
                strVar += "              <button class='btn-search-box btn-action btn-locate' onclick='params.funcs.locate(" + result.uniqueIdentifier + ")'>Locate <\/button>";
                strVar += "            <\/div>";
                strVar += "          <\/a>";
                strVar += "        <\/div>";

                return strVar;

            })
            console.log(htmlStringArray);
            var htmlString = htmlStringArray.join('');
            params.funcs.clearResult();

            var parentElement = get('.result-list');
            var old = parentElement.innerHTML;
            var newElement = htmlString + old;
            parentElement.innerHTML = newElement;
            set('.user-search-box .result-header', "RESULT - " + htmlStringArray.length);

        }

        function clearResult() {
            set('.result-list', '<div class="buffer" ></div>');
            set('.user-search-box .result-header', "RESULT");

        }

        function listen() {
            var input = get('.user-search-box .search-input');

            input.addEventListener('input', function () {
                var value = input.value ? input.value.trim() : '';
                if (value.length < 3) {
                    params.funcs.clearResult();
                } else {
                    var searchResult = params.funcs.findInTree(params.data, value);
                    params.funcs.reflectResults(searchResult);
                }

            });
        }

        function searchUsers() {

            d3.selectAll('.user-search-box')
                .transition()
                .duration(250)
                .style('width', '350px')
        }

        function closeSearchBox() {
            d3.selectAll('.user-search-box')
                .transition()
                .duration(250)
                .style('width', '0px')
                .each("end", function () {
                    params.funcs.clearResult();
                    clear('.search-input');
                });

        }

        function findInTree(rootElement, searchText) {
            var result = [];
            // use regex to achieve case insensitive search and avoid string creation using toLowerCase method
            var regexSearchWord = new RegExp(searchText, "i");

            recursivelyFindIn(rootElement, searchText);

            return result;

            function recursivelyFindIn(user) {
                if (user.name.match(regexSearchWord) ||
                    user.tags.match(regexSearchWord)) {
                    result.push(user)
                }

                var childUsers = user.children ? user.children : user._children;
                if (childUsers) {
                    childUsers.forEach(function (childUser) {
                        recursivelyFindIn(childUser, searchText)
                    })
                }
            };
        }

        function back() {

            show(['.btn-action']);
            hide(['.customTooltip-wrapper', '.btn-action.btn-back', '.department-information'])
            clear(params.selector);

            params.mode = "full";
            params.data = deepClone(params.pristinaData)
            drawOrganizationChart(params);

        }

        function expandAll() {
            expand(root);
            update(root);
        }

        function expand(d) {
            if (d.children) {
                d.children.forEach(expand);
            }

            if (d._children) {
                d.children = d._children;
                d.children.forEach(expand);
                d._children = null;
            }

            if (d.children) {
                // if node has children and it's expanded, then  display -
                setToggleSymbol(d, attrs.COLLAPSE_SYMBOL);
            }
        }

        function collapse(d) {
            if (d._children) {
                d._children.forEach(collapse);
            }
            if (d.children) {
                d._children = d.children;
                d._children.forEach(collapse);
                d.children = null;
            }

            if (d._children) {
                // if node has children and it's collapsed, then  display +
                setToggleSymbol(d, attrs.EXPAND_SYMBOL);
            }
        }

        function setCollapsibleSymbolProperty(d) {
            if (d._children) {
                d.collapseText = attrs.EXPAND_SYMBOL;
            } else if (d.children) {
                d.collapseText = attrs.COLLAPSE_SYMBOL;
            }
        }

        function setToggleSymbol(d, symbol) {
            d.collapseText = symbol;
            d3.select("*[data-id='" + d.uniqueIdentifier + "']").select('text').text(symbol);
        }

        /* recursively find logged user in subtree */
        function findmySelf(d) {
            if (d.isLoggedUser) {
                expandParents(d);
            } else if (d._children) {
                d._children.forEach(function (ch) {
                    ch.parent = d;
                    findmySelf(ch);
                })
            } else if (d.children) {
                d.children.forEach(function (ch) {
                    ch.parent = d;
                    findmySelf(ch);
                });
            }
            ;

        }

        function locateRecursive(d, id) {
            if (d.uniqueIdentifier == id) {
                expandParents(d);
            } else if (d._children) {
                d._children.forEach(function (ch) {
                    ch.parent = d;
                    locateRecursive(ch, id);
                })
            } else if (d.children) {
                d.children.forEach(function (ch) {
                    ch.parent = d;
                    locateRecursive(ch, id);
                });
            }
            ;

        }

        /* expand current nodes collapsed parents */
        function expandParents(d) {
            while (d.parent) {
                d = d.parent;
                if (!d.children) {
                    d.children = d._children;
                    d._children = null;
                    setToggleSymbol(d, attrs.COLLAPSE_SYMBOL);
                }

            }
        }

        function toggleFullScreen() {

            if ((document.fullScreenElement && document.fullScreenElement !== null) ||
                (!document.mozFullScreen && !document.webkitIsFullScreen)) {
                if (document.documentElement.requestFullScreen) {
                    document.documentElement.requestFullScreen();
                } else if (document.documentElement.mozRequestFullScreen) {
                    document.documentElement.mozRequestFullScreen();
                } else if (document.documentElement.webkitRequestFullScreen) {
                    document.documentElement.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT);
                }
                d3.select(params.selector + ' svg').attr('width', screen.width).attr('height', screen.height);
            } else {
                if (document.cancelFullScreen) {
                    document.cancelFullScreen();
                } else if (document.mozCancelFullScreen) {
                    document.mozCancelFullScreen();
                } else if (document.webkitCancelFullScreen) {
                    document.webkitCancelFullScreen();
                }
                d3.select(params.selector + ' svg').attr('width', params.chartWidth).attr('height', params.chartHeight);
            }

        }


        function showMySelf() {
            /* collapse all and expand logged user nodes */
            if (!attrs.root.children) {
                if (!attrs.root.isLoggedUser) {
                    attrs.root.children = attrs.root._children;
                }
            }
            if (attrs.root.children) {
                attrs.root.children.forEach(collapse);
                attrs.root.children.forEach(findmySelf);
            }

            update(attrs.root, {centerMySelf: true});
        }

        //locateRecursive
        function locate(id) {
            /* collapse all and expand logged user nodes */
            if (!attrs.root.children) {
                if (!attrs.root.uniqueIdentifier == id) {
                    attrs.root.children = attrs.root._children;
                }
            }
            if (attrs.root.children) {
                attrs.root.children.forEach(collapse);
                attrs.root.children.forEach(function (ch) {
                    locateRecursive(ch, id)
                });
            }

            update(attrs.root, {locate: id});
        }

        function deepClone(item) {
            return JSON.parse(JSON.stringify(item));
        }

        function show(selectors) {
            display(selectors, 'initial')
        }

        function hide(selectors) {
            display(selectors, 'none')
        }

        function display(selectors, displayProp) {
            selectors.forEach(function (selector) {
                var elements = getAll(selector);
                elements.forEach(function (element) {
                    element.style.display = displayProp;
                })
            });
        }

        function set(selector, value) {
            var elements = getAll(selector);
            elements.forEach(function (element) {
                element.innerHTML = value;
                element.value = value;
            })
        }

        function clear(selector) {
            set(selector, '');
        }

        function get(selector) {
            return document.querySelector(selector);
        }

        function getAll(selector) {
            return document.querySelectorAll(selector);
        }


    }
</script>


</body>

</html>
 
